'''
proxies.py

Copyright 2009 Xavier Mendez Navarro aka Javi

This file is part of pysqlin

pysqlin is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 2 of the License.

pysqlin is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with pysqlin; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
'''
from framework.interfaces import IModuleLoader
from framework.mymodel import InjectionData
from framework.interfaces import IFilter

import logging

class Plugins(IModuleLoader):
    def __init__(self):
	self.plugins = {}	
	self.__logger = logging.getLogger("framework.Plugins")

    # ------------------------------------------------
    # module loading
    # ------------------------------------------------
    def register(self, id, module):
	self.__logger.debug('register. START, id=%s' % (id))

	#self.plugins[module.name()] = module
	self.plugins[id] = module

    def end_loading(self, list):
	pass

    # ------------------------------------------------
    # data functions
    # ------------------------------------------------
    def names(self):
	return self.plugins.keys()

    def get(self, plugin_name):
	return self.plugins[plugin_name]

class Injectors(IModuleLoader):
    def __init__(self):
	self.plugins = {}	
	self.__logger = logging.getLogger("framework.InjectionPlugins")

    # ------------------------------------------------
    # module loading
    # ------------------------------------------------
    def register(self, id, module):
	self.__logger.debug('register. START, id=%s' % (id))

	#self.plugins[module.name()] = module
	self.plugins[id] = module

    def end_loading(self, list):
	pass

    # ------------------------------------------------
    # data functions
    # ------------------------------------------------
    def names(self):
	return self.plugins.keys()

    def get(self, plugin_name):
	m = self.plugins[plugin_name]
	return m.load(None)

class Filter:
    def __init__(self, base_filter, id):
	self.module = base_filter
	self.enabled = False
	self.priority = base_filter.priority()
	self.id = id

    def __str__(self):
	return ', '.join(
	    map(lambda x:
		{0: 'DB_QUERY',
		1: 'COOKIE',
		2: 'POST_DATA',
		3: 'URL'}[x], self.module.type()))


class Filters(IModuleLoader):
    def __init__(self):
	self.filters = {}	
	self.__logger = logging.getLogger("framework.RequestFilters")

    # ------------------------------------------------
    # module loading
    # ------------------------------------------------
    def register(self, id, module):
	self.__logger.debug('register. START, id=%s' % (id))

	self.filters[id] = Filter(module, id)

    def end_loading(self, list):
	pass

    # ------------------------------------------------
    # data functions
    # ------------------------------------------------
    def get(self, name):
	return self.filters[name].module
	
    def get_filters(self, database = None):

	if database is None or database == IFilter.DB_ALL:
	    l = self.filters.values()
	else:
	    l = [f for f in self.filters.values() if database in f.module.database() or IFilter.DB_ALL in f.module.database()]

	l.sort(self.__sorting)

	return l

    def disable_all(self):
	for f in self.filters.values():
	    f.enabled = False

    def enable_all(self):
	for f in self.filters.values():
	    f.enabled = True

    def set_state(self, filter_name, state):
	self.filters[filter_name].enabled = state

    def __sorting(self, x, y):
	return x.priority - y.priority

    def merge_sett(self, data):
	for f, k in [(self.filters[k], k) for k in data.keys() if self.filters.has_key(k)]:
	    f.enabled, f.priority = data[k]

    def names(self, db = None):
	if db is not None:
	    return [f.id for f in self.get_filters(db)]
	else:
	    return self.filters.keys()

	return l

    def get_list(self, db):
	l = [['Priority', 'Enabled', 'Type', 'Name', 'Description']]

	for filter in self.get_filters(db):
	    l.append([str(filter.module.priority()), str(filter.enabled), str(filter), filter.id, filter.module.summary()])

	return l

    # ------------------------------------------------
    # convert functions
    # ------------------------------------------------
    def process(self, injection_data):
	self.__logger.debug('process. START, data=%s' % (injection_data))

	database = injection_data[InjectionData.DATABASE]
	for f in filter(lambda x:x.enabled, self.get_filters(database)):
	    f.module.process_injection_data(injection_data)

    def process_query(self, query, database):
	self.__logger.debug('process_query. START, query=%s, db=%s' % (query, database))

	for f in filter(lambda x:x.enabled and IFilter.DB_QUERY in x.module.type(), \
			self.get_filters(database)):
	    query = f.module.process_query(query)

	return query

    def test_filter(self, name, str):
	return self.filters[name].module.transform(str)

